{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf330
{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;\f2\fnil\fcharset77 Monaco;
}
{\colortbl;\red255\green255\blue255;\red51\green51\blue179;\red137\green19\blue21;\red0\green0\blue255;
\red127\green127\blue127;}
{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid1\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid1}
{\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid2}}
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}
\margl1440\margr1440\vieww9000\viewh8440\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural

\f0\b\fs38 \cf0 Sparkle Updater\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural

\fs24 \cf0 Version 0.1
\f1\b0 \
by Andy Matuschak (andy@andymatuschak.org)\
http://www.andymatuschak.org/pages/sparkle\
\

\f0\b\fs28 Summary\
	
\f1\b0\fs24 Sparkle is a simple module that developers can drop into their apps to get free software update capabilities. It's very easy to set up (especially if you already have an appcast), and it provides many features other solutions don't, like 
\f0\b self-updating
\f1\b0 , release notes viewing, archive support (zip, dmg, tar, tgz, tbz), appcast support, and a nice status interface.\
\

\f0\b\fs28 Using Sparkle in a Project\

\f1\b0\fs24 	Sparkle is very customizable and can be used in many ways; this is just the simplest usage: a program that checks for updates on startup.
\f0\b\fs28 \

\f1\b0\fs24 \
\pard\tx220\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li720\fi-720\ql\qnatural\pardirnatural
\ls1\ilvl0\cf0 {\listtext	1.	}Drag the Sparkle folder into the Other Sources folder in your Xcode project. Make sure that the "Copy items into destination group's folder" option is checked.\
{\listtext	2.	}Instantiate SUUpdater in MainMenu.nib.\
\pard\tx940\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li1440\fi-1440\ql\qnatural\pardirnatural
\ls1\ilvl1\cf0 {\listtext	\uc0\u8259 	}Open MainMenu.nib in Interface Builder.\
{\listtext	\uc0\u8259 	}Click the Classes tab.\
{\listtext	\uc0\u8259 	}Go to Classes -> Read Files and import SUUpdater.h (which will probably be in a Sparkle subdirectory).\
{\listtext	\uc0\u8259 	}Classes -> Instantiate SUUpdater.\
\pard\tx220\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li720\fi-720\ql\qnatural\pardirnatural
\ls1\ilvl0\cf0 {\listtext	3.	}Create a "Check for updates..." menu item in the application menu and connect it to checkForUpdates: in SUUpdater.\
{\listtext	4.	}Open the desired target's Info.plist and add a SUFeedURL key set to the URL of your appcast.\
\pard\tx940\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li1440\fi-1440\ql\qnatural\pardirnatural
\ls1\ilvl1\cf0 {\listtext	\uc0\u8259 	}For example:\
{\listtext	\uc0\u8259 	}
\f2\fs20 \CocoaLigature0 <key>SUFeedURL</key>\
		<string>http://www.yourdomain.org/YourApp.xml</string>\
\pard\tx220\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li720\fi-720\ql\qnatural\pardirnatural
\ls1\ilvl0
\f1\fs24 \cf0 \CocoaLigature1 {\listtext	5.	}If necessary, update your existing appcast to fit Sparkle's requirements:\
\pard\tx940\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li1440\fi-1440\ql\qnatural\pardirnatural
\ls1\ilvl1\cf0 {\listtext	\uc0\u8259 	}The easiest way to read the version number is from the enclosure path, which should look like this: http://yourdomain.org/YourApp_0.2.5.zip. The underscore denotes the beginning of the version string.\
{\listtext	\uc0\u8259 	}Sparkle reads release notes from the description (body) field of RSS items. If you don't want them to be displayed to the user, set the SUShowReleaseNotes key to <false/> in your Info.plist. For better HTML support, add WebKit.framework to your project.\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\cf0 \
That's it! Build and run to see Sparkle in action. It'll read the current version from 
\f0\b CFBundleVersion
\f1\b0  in your Info.plist. If you set your version string through the target inspector, that's fine, too. It figures out what file to take from the archive using 
\f0\b CFBundleName
\f1\b0  (which is usually set just fine).\
\

\f0\b\fs28 Making an Appcast\

\f1\b0\fs24 	If you don't already have an appcast, you'll have to make one for Sparkle to use. They're basically just like podcasts in that they use RSS enclosures for file syndication\'d1check out http://speirs.org/appcasting/ for more info on the origin.\
\
	So really, all you have to do is create a normal RSS feed with an enclosure for each item pointing to the new version of the app. A couple things to remember:\
\
\pard\tx220\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li720\fi-720\ql\qnatural\pardirnatural
\ls2\ilvl0\cf0 {\listtext	\uc0\u8259 	}Sparkle reads the version number from the enclosure path, which should look like this: http://yourdomain.org/YourApp_0.2.5.tbz. The last underscore in the filename denotes the beginning of the version string.\
{\listtext	\uc0\u8259 	}The files you link to must be in .zip, .dmg, .tar, .tgz, or .tbz format. For .dmg, make sure the volume name contains the app's full name as specified by CFBundleName in the Info.plist.\
{\listtext	\uc0\u8259 	}If you're planning to let your users see release notes before they update (which is on by default), make sure you stick your changelog in the description (sometimes called body) field of the RSS item.\
\
		You'll have to use HTML for line breaks and paragraphs. You'll also have to escape < and > with &lt; and &gt;. Most RSS-making apps (or find-and-replace dialogs) can do this for you. \
\
		Alternately, you can just specify a web page to load release notes from here, with some caveats; read the Release Notes section of this document for more info.\
{\listtext	\uc0\u8259 	}A pubDate is required for each item (for determining which entry is newest).\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\cf0 \
Here's an example feed with an update item; just duplicate the item entry whenever you add a new build:\
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural

\f2\fs20 \cf2 <?xml version="1.0" encoding="utf-8"?>\cf0 \
\cf2 <rss version="2.0">\cf0 \
   \cf2 <channel>\cf0 \
      \cf2 <title>\cf0 YourApp Changelog\cf2 </title>\cf0 \
      \cf2 <link>\cf0 http://yourdomain.org/yourappchangelog.rss\cf2 </link>\cf0 \
      \cf2 <description>\cf0 Most recent changes with links to updates.\cf2 </description>\cf0 \
      \cf2 <language>\cf0 en\cf2 </language>\cf0       \
         \cf2 <item>\cf0 \
            \cf2 <title>\cf0 Version 2.8 (2 bugs fixed; 3 new features)\cf2 </title>\cf0 \
            \cf2 <description>- Bug #429819 closed, etc, etc</description>\cf0 \
            \cf2 <pubDate>\cf0 Wed, 06 Jan 2006 12:28:11 +0000\cf2 </pubDate>\cf0 \
            \cf2 <enclosure url="http://yourdomain/YourApp_2.8.tbz" length="5489291" type="application/octet-stream"/>\cf0 \
         \cf2 </item>\cf0 \
   \cf2 </channel>\cf0 \
\cf2 </rss>\cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural

\f1\fs24 \cf0 \
Basically, just save a file like this (customized to fit your needs), stick it on a webserver somewhere, and tell Sparkle how to find it. Many programs can help you make these feeds: Feeder's a pretty good one, though it costs money, blech.\
\

\f0\b\fs28 Adding a Check on Startup Preference\

\f1\b0\fs24 	It would be nice for you to allow your users to configure whether or not they want to check for updates on startup in case they change their minds or misclick. So if you have a preferences dialog already, all you have to do is make a check box there bound to the 
\f0\b SUCheckAtStartup
\f1\b0  user defaults key. Sparkle will fall in line.\
\

\f0\b\fs28 Scheduling a Periodic Check (and Preference)\

\f1\b0\fs24 	You might want to have your application check for updates every certain time interval (once a day, perhaps). To do this, just add a key for 
\f0\b SUScheduledCheckInterval
\f1\b0  to Info.plist. The value is specified in seconds, so once a day would be 60 * 60 * 24 = 86400.\
	\
	It's easy to make a menu in your preferences pane for the check frequency. Just update the 
\f0\b SUScheduledCheckInterval 
\f1\b0 key in the user defaults; a setting there will take precedent over the one in Info.plist. Since you probably don't want to display the interval choices in seconds, you'll have to write a quick glue method. \
\
	You'll need to let Sparkle know about the change to the check interval; just call scheduleCheckWithInterval: on your SUUpdater.\
\
	If you have a check interval specified in either location, the SUCheckAtStartup key is overridden. Instead, Sparkle will only check on startup if it's been longer than your interval since the last check. If the check interval key is in the Info.plist, Sparkle will not prompt the user for his check on startup preference the first time the application is launched.\
\
	The value specified for the check interval will be used for the Remind Me Later interval as well. If a scheduled check interval is not specified, Sparkle will remind the user half an hour after clicking Remind Me Later (provided that the app is still open then).\
\

\f0\b\fs28 Release Notes in Depth\

\f1\b0\fs24 	Sparkle's release notes feature has quite a bit of varied functionality. By default, it displays the contents of the description key in an NSTextView. However, 
\f0\b if WebKit.framework is compiled into the host app
\f1\b0 , Sparkle will use a WebView instead. This will allow full HTML, CSS, and images to be used for nicely styled release notes. Links will open in the user's default browser. Be careful about advanced Javascript usage or other things that might confuse Sparkle.\
\
	To avoid including the tremendous overhead of your release notes in your appcast, you can instead refer to a web page on your server, which will only be fetched if the user needs to update. Just set the description of an item in the feed to contain only a URL, like this (only works when WebKit is compiled in):\
\
	
\f2\fs20 \cf2 <description>http://mydomain.org/r3b2_notes.html</description>\
\

\f1\fs24 \cf0 	An extra key for sparkle:releaseNotesLink can be added to maintain a human-readable description: see the Sparkle XML Namespace section for more information.
\f2\fs20 \cf2 \
\
	
\f1\fs24 \cf0 If you would prefer not to display the release notes at all, just set SUShowReleaseNotes to <false/> like this:\
\
	
\f2\fs20 \cf3 \CocoaLigature0 <key>\cf0 SUShowReleaseNotes\cf3 </key>\cf0 \
	\cf3 <false/>\
\

\f0\b\fs28 \cf0 \CocoaLigature1 Multiple Feeds\
	
\f1\b0\fs24 If you'd like to offer your users a choice between, say, beta and stable feeds, Sparkle can make that easy. Just have your selection interface update the 
\f0\b SUFeedURL
\f1\b0  key in the user defaults\'d1whatever's set there will override the value in Info.plist.
\f2\fs20 \cf3 \CocoaLigature0 \
\

\f0\b\fs28 \cf0 \CocoaLigature1 The Sparkle XML Namespace\

\f1\b0\fs24 	Sparkle makes a couple of assumptions about the way you do things in your RSS feed that may be unsavory to one who wants the feed to be human-viewable in RSS readers and so on. To solve this, I've introduced a Sparkle XML namespace with a few items.\
\

\f0\b sparkle:version
\f1\b0 \
	If you'd like more latitude with your archive names or just don't want to be tied down to a brittle system, you can use the 
\f0\b sparkle:version
\f1\b0  attribute on <enclosure> to specify the version string for a given item. If this attribute exists, Sparkle won't parse the filename. Like so:\
\
	
\f2\fs20 \cf3 \CocoaLigature0 <enclosure sparkle:version="r3b3" url="http://opensword.org/Downloads/Pixen_r3b3.zip" length="12345" type="application/octet-stream"/>\cf0 \

\f1\fs24 \CocoaLigature1 \

\f0\b sparkle:releaseNotesLink\
	
\f1\b0 If you'd like to provide a human-readable release notes listing in your feed while still providing Sparkle with styled HTML for enticing presentation (requires WebKit compiled into the host app), you can use a 
\f0\b sparkle:releaseNotesLink
\f1\b0  key in your item to specify the URL like so:\
	\
	
\f2\fs20 \cf3 \CocoaLigature0 <sparkle:releaseNotesLink>\cf0 http://mydomain.org/myapp_\cf4 3.1\cf0 .html\cf3 </sparkle:releaseNotesLink>\
\

\f1\fs24 \cf0 \CocoaLigature1 	The URL specified in this tag will override anything in the description tag.\
\
	To use either of these features and still have good XML in your feed, you must reference to the namespace URI in your <rss> tag at the top of your feed like this:\
\
	
\f2\fs20 \cf3 \CocoaLigature0 <rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle">\cf0 \

\f1\fs24 \CocoaLigature1 \

\f0\b\fs28 Conclusion\

\f1\b0\fs24 	I hope that Sparkle will save you\'d1and your users\'d1some time and headaches. If it works well for you, please let a friend know about it! Let's put an end to manual updates together.\
\
	This software is under an MIT License (see License.txt), so you can basically do whatever you want with it. A note of thanks in an about box would be nice, though. Also, if you make any useful changes or additions, I'd love to get a copy of the patch.\
\

\f0\b\fs28 Thanks\

\f1\b0\fs24 \
Thanks to Allan Odgaard, whose code sample at http://macromates.com/sigpipe/archives/2005/10/02/determinate-progress-indicator-for-uncompressing-a-tar-bzip2-archive was modified and used for archive extraction.\
\
Thanks to codepoet for a good zip extraction implementation.\
\
Thanks to Daniel Wilson for UI criticism and advice.\
\
Thanks to David Young, who helped with the implementation of WebKit-based release notes.\
\
Thanks to Evan Schoenberg and David Smith at the Adium Project, who hooked me up with localizers and made some small changes.\
\
Thanks to M. Uli Kusterer, whose UKNiftyFeatures module inspired this project.\
\
Thanks to the following individuals for translations:\
\pard\tx440\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li100\slleading40\sb40\ql\qnatural
\cf0 	Max Bertrand
\fs20 \cf5   (French)
\fs24 \cf0 \
	Frantisek Erben
\fs20 \cf5   (Czech)
\fs24 \cf0 \
	Bu\uc0\u287 ra Henden 
\fs20 \cf5 (Turkish)
\fs24 \cf0  \
	Jack M.H. Lin
\fs20 \cf5   (Traditional Chinese)
\fs24 \cf0 \
	Daisuke Okada  
\fs20 \cf5 (Japanese)
\fs24 \cf0 \
	Nicola "ATMB" Del Monaco  
\fs20 \cf5 (Italian)\

\fs24 \cf0 	Peter Piln\'8as 
\fs20 \cf5 (Swedish)
\fs24 \cf0 \
	Marc S. Re\'a7l  
\fs20 \cf5 (Catalan)\

\fs24 \cf0 	Stef\'87n Vignir Skarph\'8e\uc0\u240 insson  
\fs20 \cf5 (Icelandic)\
	
\fs24 \cf0 \uc0\u1042 \u1072 \u1083 \u1077 \u1085 \u1090 \u1080 \u1085  \u1055 \u1072 \u1088 \u1085 \u1072 \u1093   
\fs20 \cf5 (Russian)
\fs24 \cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\cf0 \
Thanks to Brent Simmons, whose RSS reader class was modified and used for appcast support. His class (not Sparkle itself) is licensed as follows:\
\
BSD License\
\
Copyright (c) 2002, Brent Simmons\
All rights reserved.\
\
Redistribution and use in source and binary forms, with or without modification,\
are permitted provided that the following conditions are met:\
\
*	Redistributions of source code must retain the above copyright notice,\
	this list of conditions and the following disclaimer.\
*	Redistributions in binary form must reproduce the above copyright notice,\
	this list of conditions and the following disclaimer in the documentation\
	and/or other materials provided with the distribution.\
*	Neither the name of ranchero.com or Brent Simmons nor the names of its\
	contributors may be used to endorse or promote products derived\
	from this software without specific prior written permission.\
\
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS\
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\
}